package com.parleys.android.client.ui;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.BaseColumns;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.parleys.android.client.R;
import com.parleys.android.client.provider.ParleysContract.News;
import com.parleys.android.client.service.ParleysService;
import com.parleys.android.client.service.ParleysServiceHelper;
import com.parleys.android.client.util.DetachableResultReceiver;
import com.parleys.android.client.util.DetachableResultReceiver.Receiver;
import com.parleys.android.client.util.NotifyingAsyncQueryHandler;
import com.parleys.android.client.util.NotifyingAsyncQueryHandler.AsyncQueryListener;
import com.parleys.android.client.util.ParserUtils;
import com.parleys.android.client.util.UIUtils;

public class NewsActivity extends ListActivity implements AsyncQueryListener, Receiver {
	
	private static final String TAG = "NewsActivity";
	
    private State mState;

    private static ParleysServiceHelper parleysServiceHelper = ParleysServiceHelper.getInstance();
    private Uri mNewsUri;
	private NotifyingAsyncQueryHandler mHandler;
    private NewsAdapter mAdapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.activity_news);

        mState = (State) getLastNonConfigurationInstance();
        final boolean previousState = mState != null;

        mNewsUri = this.getIntent().getData();

        mAdapter = new NewsAdapter(this);
        setListAdapter(mAdapter);

        mHandler = new NotifyingAsyncQueryHandler(this, this);
        startQuery();

        if (previousState) {
            mState.mReceiver.setReceiver(this);
            updateRefreshStatus();
        } else {
            mState = new State();
            mState.mReceiver.setReceiver(this);
            parleysServiceHelper.getGeneralNews(this, mState.mReceiver);
        }
	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();
		final Window window = getWindow();
		window.setFormat(PixelFormat.RGBA_8888);
	}
	
	@Override
    public Object onRetainNonConfigurationInstance() {
        mState.mReceiver.clearReceiver();
        return mState;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

	public void onQueryComplete(int token, Object cookie, Cursor cursor) {
		cursor.setNotificationUri(getContentResolver(), mNewsUri);
		startManagingCursor(cursor);
		mAdapter.changeCursor(cursor);
	}

	public void onHomeClick(View v) {
		UIUtils.goHome(this);
	}
	
    @Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
        final Cursor cursor = (Cursor) mAdapter.getItem(position);
        final int newsId = cursor.getInt(NewsQuery.NEWS_ID);
        final Uri newsUri = News.buildNewsUri(newsId);
        final Intent intent = new Intent(Intent.ACTION_VIEW, newsUri);
        startActivity(intent);
	}

	private void startQuery() {
    	mHandler.cancelOperation(NewsQuery.TOKEN);
        mHandler.startQuery(NewsQuery.TOKEN, null, mNewsUri, NewsQuery.PROJECTION, null, null, NewsQuery.SORT);
    }
    
    private void updateRefreshStatus() {
        findViewById(R.id.refresh_news_separator).setVisibility(mState.mSyncing ? View.VISIBLE : View.GONE);
        findViewById(R.id.refresh_news_progress).setVisibility(mState.mSyncing ? View.VISIBLE : View.GONE);
    }
    
    /** {@inheritDoc} */
    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case ParleysService.STATUS_RUNNING: {
                mState.mSyncing = true;
                updateRefreshStatus();
                break;
            }
            case ParleysService.STATUS_FINISHED: {
                mState.mSyncing = false;
                updateRefreshStatus();
                break;
            }
            case ParleysService.STATUS_ERROR: {
                mState.mSyncing = false;
                updateRefreshStatus();
                break;
            }
        }
    }

    public static final class NewsItemViews {
        View unreadView;
        TextView titleView;
        TextView itemView;
    }

    private class NewsAdapter extends CursorAdapter {
    	
		public NewsAdapter(Context context) {
			super(context, null);
		}

	    protected void findAndCacheViews(View view) {
	    	NewsItemViews views = new NewsItemViews();
	        views.unreadView = view.findViewById(R.id.news_unread);
	        views.titleView = (TextView) view.findViewById(R.id.news_title);
	        views.itemView = (TextView) view.findViewById(R.id.news_item);
	        view.setTag(views);
	    }

	    @Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = getLayoutInflater().inflate(R.layout.list_item_news, parent, false);
            findAndCacheViews(v);
            return v;
		}
    	
		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			NewsItemViews views = (NewsItemViews) view.getTag();
			
			final String title = cursor.getString(NewsQuery.TITLE);
			final String item = cursor.getString(NewsQuery.ITEM);
			
			views.unreadView.setVisibility((cursor.getInt(NewsQuery.READ) == 1) ? View.INVISIBLE : View.VISIBLE);
            views.titleView.setText(title);
            views.itemView.setText(ParserUtils.stripHtmlTags(item));
		}

    }
    
    private static class State {
        public DetachableResultReceiver mReceiver;
        public boolean mSyncing = false;

        private State() {
            mReceiver = new DetachableResultReceiver(new Handler());
        }

    }

    private interface NewsQuery {
    	int TOKEN = 0x01;
    	
        String[] PROJECTION = {
                BaseColumns._ID,
                News.NEWS_ID,
                News.TITLE,
                News.ITEM,
                News.READ,
        };
        
        String SORT = News.DEFAULT_SORT;

        int _ID 		= 0;
        int NEWS_ID 	= 1;
        int TITLE		= 2;
        int ITEM		= 3;
        int READ		= 4;		
    }

}
